package com.hxx.service.ai.impl;

import com.hxx.dto.OrderRequest;
import com.hxx.mapper.DishMapper;
import com.hxx.service.ai.OrderAiService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OpenAiOrderService implements OrderAiService {

    @Autowired
    private DishMapper dishMapper;

    // 创建一个ChatClient实例，用于与OpenAI对话
    private ChatClient chatClient;

    // 构造函数，用于初始化ChatClient实例
    public OpenAiOrderService(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.defaultOptions(ChatOptions.builder()
                .build()).build();
    }

    // 系统提示信息，包含可用菜品列表和订单请求格式
    private final String SYSTEM_PROMPT = """
        你是一个智能点餐助手，负责将用户的自然语言点餐内容转换为结构化的订单信息。
        可用的菜品列表如下：
        {dishes}
        
        结构化订单信息的格式为：
        {format}
        """;

    /**
     * 将自然语言订单转换为结构化订单请求
     *
     * 此方法接收一段自然语言输入，并将其解析为一个订单请求对象它通过以下步骤实现：
     * 1. 获取所有可用菜品信息
     * 2. 准备订单请求的格式化模板
     * 3. 创建包含菜品信息和格式化模板的提示词
     * 4. 将提示词和自然语言输入发送给AI模型，并接收响应
     * 5. 将AI模型的响应解析为订单请求对象
     *
     * @param naturalLanguageInput 自然语言订单描述
     * @return 解析后的订单请求对象
     * @throws RuntimeException 如果解析过程中发生错误
     */
    @Override
    public OrderRequest parseNaturalLanguageOrder(String naturalLanguageInput) {
        try {
            // 获取所有可用菜品
            String dishesInfo = dishMapper.selectList(null).stream()
                    .map(dish -> String.format("ID:%d - %s, 价格:%.2f元",
                            dish.getId(), dish.getName(), dish.getPrice()))
                    .collect(Collectors.joining("\n"));// 将菜品信息以换行符分隔

            // 创建一个用于转换JSON到OrderRequest对象的转换器
            BeanOutputConverter<OrderRequest> beanOutputConverter =
                    new BeanOutputConverter<>(OrderRequest.class);

            // 获取转换器的格式化字符串
            String format = beanOutputConverter.getFormat();

            // 创建提示词，包含系统信息、菜品信息和期望的输出格式
            PromptTemplate promptTemplate = new PromptTemplate(SYSTEM_PROMPT,
                    Map.of("dishes", dishesInfo, "format", format));

            // 发送到AI并获取响应
            String response = chatClient.prompt()
                    .system(promptTemplate.render())
                    .user(naturalLanguageInput)
                    .call()
                    .content();

            // 解析JSON响应
            return beanOutputConverter.convert(response);

        } catch (Exception e) {
            // 如果发生异常，抛出运行时异常
            e.printStackTrace();
            throw new RuntimeException("无法解析订单信息", e);
        }
    }
}
